package com.zdsoft.site.mina.model;

import com.hundsun.encrypt.Mac;
import com.hundsun.encrypt.util.HsParam;
import com.hundsun.encrypt.util.StringUtil;
import com.zdsoft.site.mina.p2p.P2PIoHandler;

/**
 *	请求包头部
 *	以上包头总长为 57字节长度请求与应答时均固定不变。 
 *	通讯时可以先收取前 9 字节判断后再做后续包的收取，也可先固定收取 57字节通讯头长度再根据
 *	通讯头第三个域里的长度收取 xml报文的长度。
 * 	@author cqyhm
 *
 */
public class PackageHeader {
	/**1 字节报文性质 “X”-表示xml类型报文。  */
	private String type="X";
	/**3字节为通讯头的全长,一般固定为“057”。 */
	private String headLength="057";
	/**5字节为其后的XML数据报文全长，不足左补零。不包含包头的 57字节固定长度。*/
	private String bodyLength="0";
	/**8字节为监管系统对连接的服务商或交易所的编号用于确定是哪家接入服务商。 */
	private String InstId="";
	/**5字节为托管系统内部交易编码。*/
	private String InstrCd;
	/**3字节加密标志 
      *加密情况标志固定 3字节。密码加密标志：表示通讯加密方式，固定 3字节长度，
      *第一字节：密码加密标志;
      *第二字节：MAC加密标志;
      *第三字节：报文加密标志。*/
	private String flag="";
	/**32字节MAC值不足为左补空格。 */
	private String mac="0";
	
	public PackageHeader(){}
	public PackageHeader(String in){
		//解析字符串头
		if(in!=null&&in.length()==57){
			setType(in.substring(0,1));
			setHeadLength(in.substring(1, 4));
			setBodyLength(in.substring(4,9));
			setInstId(in.substring(9,17));
			setInstrCd(in.substring(17,22));
			setFlag(in.substring(22,25));
			setMac(in.substring(25,57));
		}
	}
	/**1 字节报文性质 “X”-表示xml类型报文。  */
	public String getType() {
		return type;
	}
	/**1 字节报文性质 “X”-表示xml类型报文。  */
	public void setType(String type) {
		this.type = type;
	}
	/**3字节为通讯头的全长,一般固定为“057”。 */
	public int getHeadLength() {
		return Integer.valueOf(headLength);
	}
	/**3字节为通讯头的全长,一般固定为“057”。 */
	public void setHeadLength(String headLength) {
		this.headLength = headLength;
	}
	/**3字节为通讯头的全长,一般固定为057。 */
	public void setHeadLength(Integer headLength) {
		setHeadLength(String.format("%03d", headLength));		
	}
	/**5字节为其后的XML数据报文全长，不足左补零。不包含包头的 57字节固定长度。*/
	public int getBodyLength() {
		return Integer.valueOf(bodyLength);
	}
	/**5字节为其后的XML数据报文全长，不足左补零。不包含包头的 57字节固定长度。*/
	public void setBodyLength(String bodyLength) {
		this.bodyLength = bodyLength;
	}
	/**5字节为其后的XML数据报文全长，不足左补零。不包含包头的 57字节固定长度。*/
	public void setBodyLength(Integer bodyLength) {
		setBodyLength(String.format("%05d", bodyLength));
	}
	/**8字节为监管系统对连接的服务商或交易所的编号用于确定是哪家接入服务商。 */
	public String getInstId() {
		return InstId;
	}
	/**8字节为监管系统对连接的服务商或交易所的编号用于确定是哪家接入服务商。 */
	public void setInstId(String instId) {
		InstId = instId;
	}
	/**5字节为托管系统内部交易编码。*/
	public String getInstrCd() {
		return InstrCd;
	}
	/**5字节为托管系统内部交易编码。*/
	public void setInstrCd(String instrCd) {
		InstrCd = instrCd;
	}
	/**
	 * 检查包中的mac和生成的mac是否相等
	 */
	public boolean checkMac(String text){
		if("1".equals(getFlag().substring(1, 2))){
			String receivMac=StringUtil.rightPad(Mac.generateMAC(HsParam.HS_ENC, text, P2PIoHandler.macKey),32,"0");
			return receivMac.equals(mac);	
		}else{
			return true;
		}
	}
	/**3字节加密标志 
     *加密情况标志固定 3字节。
     *密码加密标志：表示通讯加密方式，固定 3字节长度，
     *		 第一字节：密码加密标志;
     *		 第二字节：MAC加密标志;
     *		 第三字节：报文加密标志。
     * 密码加密，16位字符长度： 0
	 * 		   当标志＝1时，使用交换的密码密钥进行DES加密；
	 * 		   当标志＝2时，不加密处理，使用密码原文传输；
	 * 		  当标志为其他时，则使用固定的密码密钥进行DES加密，此密码密钥需要银行事先和服务商约定。
	 * MAC加密，8字符长度：      1
	 * 		   当标志＝0时，不进行MAC处理，包头中的MAC为8位’ ’（空格）.
	 * 		   如标志＝1时，则为报文的MAC值.
	 * 报文加密：                               2
	 * 		  当标志＝0时，不进行报文加密处理.
	 *       如标志＝1时，使用固定的报文密钥进行全报文DES加密.
	 *       如标志＝2时，使用固定的报文密钥进行全报文3-DES加密.
     **/
	public String getFlag() {
		return flag;
	}
	/**3字节加密标志 
     *加密情况标志固定 3字节。密码加密标志：表示通讯加密方式，固定 3字节长度，第一字节：
     *密码加密标志;第二字节：MAC加密标志;第三字节：报文加密标志。*/
	public void setFlag(String flag) {
		this.flag = flag;
	}
	/**32字节MAC值不足为左补空格(错误)。实际上是右边补0 */
	public String getMac() {
		return mac;
	}
	/**32字节MAC值不足为左补空格(错误)。实际上是右边补0 */
	public void setMac(String mac) {
		if(mac!=null && mac.length()<32){
			this.mac = StringUtil.rightPad(mac, 32,"0");//不足32位后边补0
			//this.mac = StringUtil.leftPad(mac, 32);//左边补空格
		}else{
			this.mac = mac;
		}
	}
	/**
	 * @return
	 */
	@Override	
	public String toString(){
		return String.format("%s%s%s%s%s%s%s", type,headLength,bodyLength,InstId,InstrCd,flag,mac);
	}
	
	public String toValue() {
		StringBuilder builder = new StringBuilder();
		builder.append("PackageHeader [type=").append(type).append(", headLength=").append(headLength).append(", bodyLength=").append(bodyLength).append(", InstId=").append(InstId).append(", InstrCd=").append(InstrCd).append(", flag=").append(flag).append(", mac=").append(mac).append("]");
		return builder.toString();
	}
}
